package com.chang.bootplus.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chang.bootplus.base.exception.BusException;
import com.chang.bootplus.base.utils.ApiResponse;
import com.chang.bootplus.base.utils.BeanUtil;
import com.chang.bootplus.entity.MatrixOrder;
import com.chang.bootplus.entity.MatrixOrderDetails;
import com.chang.bootplus.entity.Product;
import com.chang.bootplus.entity.ProductUnit;
import com.chang.bootplus.mapper.MatrixOrderMapper;
import com.chang.bootplus.po.*;
import com.chang.bootplus.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chang.bootplus.vo.LocationVO;
import com.chang.bootplus.vo.OrderVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ning
 * @since 2022-01-25
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MatrixOrderServiceImp extends ServiceImpl<MatrixOrderMapper, MatrixOrder> implements MatrixOrderService {

    final MatrixOrderDetailsService matrixOrderDetailsService;
    final MatrixOrderMapper matrixOrderMapper;
    final ProductService productService;
    final ProductUnitService productUnitService;
    final UserLocationService userLocationService;

    @Override
    public ApiResponse<OrderVO> listOrder(OrderSelPO po) {
        po.setPageNumber(po.getPageNumber()-1);
        List<MatrixOrder> orders = matrixOrderMapper.listOrder(po);

        List<OrderVO> orderVOS = orders.stream().map(order ->
                BeanUtil.beanA2beanB(order, OrderVO.class).setDetailsList(
                        matrixOrderDetailsService.list(new LambdaQueryWrapper<MatrixOrderDetails>().
                                eq(MatrixOrderDetails::getOrderId, order.getId())))
                        .setUserLocation(BeanUtil.beanA2beanB(userLocationService.getById(order.getUserLocationId()), LocationVO.class))
                        .setBusLocation(BeanUtil.beanA2beanB(userLocationService.getById(order.getBusLocationId()), LocationVO.class))
        ).collect(Collectors.toList());

        return new ApiResponse<>(orderVOS);
    }

    @Override
    public ApiResponse<Void> addOrder(OrderPO po) {
        MatrixOrder order = BeanUtil.beanA2beanB(po, MatrixOrder.class);
        //1.UUID生成32位数
        String uuid32 = UUID.randomUUID().toString().replace("-", "");
        //2.然后截取前面或后面16位
        String uuid16 = uuid32.substring(0, 16);
        order.setOrderId(uuid16);
        save(order);
        Long id = getOne(new LambdaQueryWrapper<MatrixOrder>().eq(MatrixOrder::getOrderId, uuid16)).getId();

        List<OrderDetailPO> detailsList = po.getDetailsList();
        detailsList.forEach(orderDetailPO -> {
            matrixOrderDetailsService.save(BeanUtil.beanA2beanB(orderDetailPO, MatrixOrderDetails.class).setOrderId(id));
        });

        return new ApiResponse().setReMsg("存储成功");
    }

    @Override
    public ApiResponse<Void> updateOrder(OrderListPO po) {
        List<OrderDetailPO> detailsList = po.getDetailsList();
        if(!(detailsList == null || detailsList.size()==0)){
            matrixOrderDetailsService.remove(new LambdaQueryWrapper<MatrixOrderDetails>().
                    eq(MatrixOrderDetails::getOrderId,po.getId()));
            detailsList.stream().forEach(orderDetailPO -> {
                matrixOrderDetailsService.save(BeanUtil.beanA2beanB(orderDetailPO, MatrixOrderDetails.class)
                        .setOrderId(po.getId()));
            });
        }

        MatrixOrder matrixOrder = BeanUtil.beanA2beanB(po, MatrixOrder.class);
        updateById(matrixOrder);
        return new ApiResponse().setReMsg("更新成功");
    }

    @Override
    public ApiResponse<Void> deleteOrder(OrderIdPO po) {
        boolean b1 = matrixOrderDetailsService.remove(new LambdaQueryWrapper<MatrixOrderDetails>().
                eq(MatrixOrderDetails::getOrderId,po.getId()));
        if (!b1){
            throw new BusException("删除失败");
        }

        boolean b2 = removeById(po.getId());
        if (!b2){
            throw new BusException("删除失败");
        }

        return new ApiResponse().setReMsg("删除成功");
    }

    @Override
    public ApiResponse<Void> receiveOrder(OrderIdPO po) {
        MatrixOrder order = getOne(new LambdaQueryWrapper<MatrixOrder>().eq(MatrixOrder::getId, po.getId()));
        if(order.getPayStatus().equals(0)){
            throw new BusException("还未支付不能收货！");
        }
        if(order.getDeliverStatus().equals(0)){
            throw new BusException("还未发货不能收货！");
        }
        if(order.getReceiveStatus().equals(1)){
            throw new BusException("已经收货了,不可重复收货！");
        }
        order.setReceiveStatus(1);
        order.setReceiveTime(LocalDateTime.now());
        List<MatrixOrderDetails> proList = matrixOrderDetailsService.
                list(new LambdaQueryWrapper<MatrixOrderDetails>().eq(MatrixOrderDetails::getOrderId, po.getId()));

        //你交易的此订单的对应的商品若已经不存在了，则销量无法增加
        boolean b0 = updateById(order);
        if (!b0){
            throw new BusException("收货失败");
        }
        for (MatrixOrderDetails pro : proList) {
            Product p = productService.getById(pro.getProId());
            if (p.getProStatus().equals(0)) {
                p.setSellnum(p.getSellnum()+1);
                boolean b = productService.updateById(p);
                if(!b){
                    throw new BusException("销量增加出现异常");
                }
            }
            Long proOfUnitId = p.getCategoryIdFour();
            ProductUnit proOfUnit = productUnitService.getById(proOfUnitId);
            proOfUnit.setSellnum(proOfUnit.getSellnum()+1);
            boolean bb = productUnitService.updateById(proOfUnit);
            if(!bb){
                throw new BusException("商品单元销量增加出现异常");
            }
        }
        return new ApiResponse().setReMsg("收货成功");
    }

    @Override
    public ApiResponse<Void> deliverOrder(OrderIdPO po) {
        MatrixOrder order = getOne(new LambdaQueryWrapper<MatrixOrder>().eq(MatrixOrder::getId, po.getId()));
        if(order.getPayStatus().equals(0)){
            throw new BusException("还未支付不能发货！");
        }
        if(order.getReceiveStatus().equals(1)){
            throw new BusException("已经发货了,不可重复发货！");
        }
        order.setDeliverStatus(1);
        order.setDeliverTime(LocalDateTime.now());
        boolean b = updateById(order);
        if (!b){
            throw new BusException("发货失败");
        }
        return new ApiResponse().setReMsg("发货成功");
    }

    @Override
    public ApiResponse<Void> payOrder(OrderIdPO po) {
        MatrixOrder order = getOne(new LambdaQueryWrapper<MatrixOrder>().eq(MatrixOrder::getId, po.getId()));
        if(order.getPayStatus().equals(1)){
            throw new BusException("已经支付了,不可重复支付！");
        }
        order.setPayStatus(1);
        order.setPayTime(LocalDateTime.now());
        boolean b = updateById(order);
        if (!b){
            throw new BusException("支付失败");
        }
        return new ApiResponse().setReMsg("支付成功");
    }
}
